package eerbaar.client.internal.ctr.operator;

import eerbaar.client.exp.ExpException;
import eerbaar.client.exp.IExp;
import eerbaar.client.exp.IScope;
import eerbaar.client.exp.IState;
import eerbaar.client.exp.Numeric;
import eerbaar.client.exp.ScopeManager;
import eerbaar.client.internal.ctr.operator.area.ValueArea;
import eerbaar.client.internal.ctr.operator.area.ValueAreaPopulator;
import eerbaar.game.IGame;
import eerbaar.persona.IPersona;
import eerbaar.position.IPosition;

abstract class AbstractExp implements IExp {

    private String elementName;
    private int numeric;
    private int patternNumer;

    public AbstractExp(IExp[] array) {

        if (array.length == 1) {
            IExp exp = array[0];
            this.elementName = exp.toString();
            this.numeric = 5;
            this.patternNumer = 0;
        } else if (array.length == 2) {
            for (IExp exp : array) {
                if (Numeric.isNumeric(exp.toString())) {
                    this.numeric = Integer.parseInt(exp.toString());
                } else {
                    this.elementName = exp.toString();
                }
            }
            this.patternNumer = 0;
        } else if (array.length == 3) {
            for (int i = 0; i < array.length; i++) {
                IExp exp = array[i];
                if (i == 0) {
                    this.numeric = Integer.parseInt(exp.toString());
                } else if (i == 1) {
                    this.patternNumer = Integer.parseInt(exp.toString());
                } else {
                    this.elementName = exp.toString();
                }
            }
        } else {
            this.elementName = "";
            this.numeric = 5;
        }
    }

    @Override
    public IPosition calcDestination(IScope scope) {

        IGame game = (IGame) scope.getGame();

        IExp[] exps = new IExp[] { this };

        ValueArea va = (ValueArea) scope.getValueArea();
        if (va == null) {
            va = new ValueArea(game);
            scope.setValueArea(va);
        }
        ValueAreaPopulator populator = new ValueAreaPopulator(va, game, exps);

        IPosition p = null;
        {
            ScopeManager manager = scope.getScopeManager();
            IScope subScope = manager.pushScope("sub");
            subScope.setValueArea(populator.getValueArea());

            p = populator.calcDestination(subScope);

            manager.popScope();
        }

        return p;
    }

    protected String getElementName() {
        return this.elementName;
    }

    public int getNumeric() {
        return this.numeric;
    }

    public int getPatternNumer() {
        return this.patternNumer;
    }

    @Override
    public IScope interpret(IScope inScope) throws ExpException {

        IScope scope = inScope;

        IPersona pet = (IPersona) scope.getTarget();
        IGame game = (IGame) scope.getGame();

        this.populateValueArea(scope);
        IPosition p = calcDestination(scope);

        IExp exp = null;
        if (p != null) {
            exp = Global.calcMoveTo(game, pet, pet.getPosition(), p);
        }

        IState state = scope.getState();
        if (exp == null) {
            state.setFinished(true);
        } else {
            exp.interpret(scope);
            state.setFinished(false);
        }

        return scope;
    }

    @Override
    public boolean isInteresting(String elementName) {

        if (this.elementName == null) {
            return false;
        }

        return elementName.equals(this.elementName);
    }

}
